package particle;

import genetic.Fish;
import autonomous.FlockBoid;
import processing.core.PApplet;
import processing.core.PVector;

// A very basic Repeller class
public class Repeller extends PApplet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// Gravitational Constant
	float G = (float) 50;

	// Location
	PVector loc;

	float r = 30;

	// For mouse interaction
	boolean dragging = false; // Is the object being dragged?
	boolean rollover = false; // Is the mouse over the ellipse?
	PVector drag; // holds the offset for when object is clicked on

	PApplet parent; // The parent PApplet that we will render ourselves onto

	public Repeller(PApplet p, float x, float y) {
		parent = p;
		loc = new PVector(x, y);
		drag = new PVector(p.mouseX, p.mouseY);
	}

	public void display() {
		parent.fill(100, 11, 100);
		parent.ellipse(loc.x, loc.y, r * 3, r * 3);
	}

	// Calculate a force to push particle away from repeller
	public PVector pushBoid(FlockBoid fBoid) {

		PVector dir = PVector.sub(fBoid.loc.get(), loc); // Calculate
		// direction of
		// force
		float d = dir.mag(); // Distance between objects
		dir.normalize(); // Normalize vector (distance doesn't matter here, we
							// just want this vector for direction)
		d = constrain(d, 1, 10); // Keep distance within a reasonable range
		float force = -1 * G / (d * d * d); // Repelling force is inversely
		// proportional to distance
		dir.mult(force); // Get force vector --> magnitude *
							// direction
		return dir;
	}
	public PVector harmFish(Fish fish) {

		PVector dir = PVector.sub(fish.loc.get(), loc); // Calculate
		// direction of
		// force
		float d = dir.mag(); // Distance between objects
		dir.normalize(); // Normalize vector (distance doesn't matter here, we
							// just want this vector for direction)
		d = constrain(d, 1, 10); // Keep distance within a reasonable range
		float force = -1 * G / (d * d * d); // Repelling force is inversely
		// proportional to distance
		dir.mult(force); // Get force vector --> magnitude *
							// direction
		return dir;
	}

	public boolean motion(FlockBoid f, Repeller r) {

		PVector dir = PVector.sub(f.loc.get(), r.loc.get()); // Calculate
		float d = dir.mag(); // Distance between objects
		if (d < (float) 2)
			return true;
		else
			return false;
	}

	// The methods below are for mouse interaction
	public void clicked(int mx, int my) {
		float d = dist(mx, my, loc.x, loc.y);
		if (d < r) {
			dragging = true;
			drag.x = loc.x - mx;
			drag.y = loc.y - my;
		}
	}

	public void rollover(int mx, int my) {
		float d = dist(mx, my, loc.x, loc.y);
		if (d < r) {
			rollover = true;
		} else {
			rollover = false;
		}
	}

	public void stopDragging() {
		dragging = false;
	}

	public void drag() {
		if (dragging) {
			loc.x = parent.mouseX + drag.x;
			loc.y = parent.mouseY + drag.y;
		}
	}

}
